package com.moth.cloudsequence;

/**
 * 
 */

import java.io.File;
import java.sql.Date;
import java.util.ArrayList;
import java.util.List;

import com.moth.ISystemConstant;
import com.moth.utils.ConvertHelper;
import com.moth.utils.DateUtil;
import com.moth.utils.FileOperateHelper;

/**
 * 测试文件序列并发 作者:龙色波 日期:2013-12-23
 */
public class FileSequenceTestSync {

	/**
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		int threadnum = 1000;
		if (args.length > 0) {
			threadnum = ConvertHelper.toInt(args[0]);
		}
		String workPath = "";
		String serverPath = "";
		String sequencename = "";
		if (args.length > 1) {
			workPath = args[1];
		}
		if (args.length > 2) {
			serverPath = args[2];
			if (!serverPath.endsWith(File.separator)) {
				serverPath = serverPath + File.separator;
			}
		}
		if (args.length > 3) {
			sequencename = args[3];
		}
		CloudSequenceServer.start(10, workPath, serverPath);
		List<SyncGetNextSeqVal> threads = new ArrayList<SyncGetNextSeqVal>();
		long begintime, endtime;
		begintime = System.currentTimeMillis();
		System.out.println("threadNum:"+threadnum);
		for (int i = 0; i < threadnum; i++) {
			SyncGetNextSeqVal thread = new SyncGetNextSeqVal(sequencename);
			threads.add(thread);
			thread.start();
			while (threads.size() > 1000) {
				int waittime = ISystemConstant.THREAD_WAIT_SLEEP_TIME;
				if (waittime > 20000) {
					waittime = ISystemConstant.THREAD_WAIT_SLEEP_TIME;
				} else {
					waittime = waittime + 1;
				}
				Thread.sleep(waittime);
				removeEndThreads(workPath, threads,1000);
			}
		}
		removeEndThreads(workPath, threads,0);
		endtime = System.currentTimeMillis();
		System.out.println("--Sum cost time:" + (endtime - begintime));
		CloudSequenceServer.stop();
	}

	private static void removeEndThreads(String serverPath,
			List<SyncGetNextSeqVal> threads, int threadNum) throws Exception {
		int waittime = ISystemConstant.THREAD_WAIT_SLEEP_TIME;
		String logFileName = serverPath + "insert.sql";
		while (threads.size()>threadNum) {
			for (int i = threads.size() - 1; i >= 0; i--) {
				if (!threads.get(i).isAlive()) {
					String msg;
					msg = "insert into test(id) values('"
							+ threads.remove(i).getSeqval() + "');\r\n";
					FileOperateHelper.writeStringToFile(new File(logFileName),
							msg, ISystemConstant.UTF_8_ENCODE, true);
				}
			}
			try {
				if (!threads.isEmpty()) {
					if (waittime > 20000) {
						waittime = ISystemConstant.THREAD_WAIT_SLEEP_TIME;
					} else {
						waittime = waittime + 1;
					}
					Thread.sleep(waittime);
				}
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

class SyncGetNextSeqVal extends Thread {
	private String sequenceName;
	private String seqval;

	public SyncGetNextSeqVal(String sequenceName) {
		this.sequenceName = sequenceName;
	}

	@Override
	public void run() {
		long begintime, endtime;
		try {
			begintime = System.currentTimeMillis();
			Date d = new Date(System.currentTimeMillis());
			seqval = CloudSequenceServer.getNextSeqVal(sequenceName, d, d, d);
			endtime = System.currentTimeMillis();
			System.out.println(DateUtil.getNowTimeStampString() + ",seqval:"
					+ seqval + ",cost time:" + (endtime - begintime));
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public String getSeqval() {
		return seqval;
	}

};
